package com.rongshu.view.submitArticle.presenter;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Html;
import android.text.TextUtils;
import android.widget.EditText;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.luck.picture.lib.PictureSelectionModel;
import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;
import com.rongshu.R;
import com.rongshu.api.FileUploadService;
import com.rongshu.api.RetorfitService;
import com.rongshu.utils.BitmapUtils;
import com.rongshu.utils.Common;
import com.rongshu.utils.Constant;
import com.rongshu.utils.FileUtils;
import com.rongshu.utils.UserInfoUtils;
import com.rongshu.view.base.BaseActivity;
import com.rongshu.view.base.mvp.BasePresenter;
import com.rongshu.view.home.activity.SelectFloderActivity;
import com.rongshu.view.submitArticle.activity.SubmitArticleActivity;
import com.rongshu.view.submitArticle.activity.SubmitArticleSettingActivity;
import com.rongshu.view.submitArticle.bean.DraftResponse;
import com.rongshu.view.submitArticle.bean.SavaDraftBody;
import com.rongshu.view.submitArticle.bean.SaveDraftResponse;
import com.rongshu.view.submitArticle.view.SaveDraftView;
import com.rongshu.view.userInfo.entity.UpLoadImage;
import com.rongshu.widget.BanyanDialog;
import com.utils.LogUtil;
import com.utils.StringUtils;
import com.utils.permissions.OnPermission;
import com.utils.permissions.XXPermissions;
import com.widget.toast.ToastUtils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import rx.Subscriber;
import rx.functions.Action0;
import top.zibin.luban.CompressionPredicate;
import top.zibin.luban.Luban;
import top.zibin.luban.OnCompressListener;

import static com.rongshu.view.submitArticle.activity.SubmitArticleActivity.FINISH_SUBMIT_ARTICLE;
import static com.rongshu.view.submitArticle.activity.SubmitArticleActivity.SUBMIT_ARTICLE_SELECT_FLODER;
import static com.rongshu.view.submitArticle.activity.SubmitArticleActivity.UPLOAD_COVER;
import static com.rongshu.view.submitArticle.activity.SubmitArticleActivity.UPLOAD_ILLUSTRATION;

/**
 * created by zhengweis on 2018/11/19.
 * description：
 */
public class SubmitArticlePresenter extends BasePresenter<SaveDraftView> {
    private BanyanDialog dialog;
    private BaseActivity activity;
    public static int SAVE_DRIFT = 2;
    public static int DELETE_DRIFT = 1;
    private String[] permissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
    private Handler mHandler;
    //草稿内容中的图片，以键(url)值(bitmap)对保存
    private Map<String, Bitmap> bitmapMap;
    private int count = 0;
    //草稿内容中的图片url
    private List<String> urls;

    public SubmitArticlePresenter(Context context) {
        super(context);
        activity = (BaseActivity) mContext;
        mHandler = new Handler();
        bitmapMap = new HashMap<>();
    }

    public void showHintDialog() {
        BanyanDialog.Builder builder = new BanyanDialog.Builder(mContext);
        builder.setTitle(mContext.getString(R.string.exit_draft_hint_title));
        builder.setContent(mContext.getString(R.string.exit_draft_hint_content));
        builder.setLeft("不保存");
        builder.setRight(mContext.getString(R.string.save));
        builder.setDialogOnClick(new BanyanDialog.Builder.onClickListener() {
            @Override
            public void leftClickListener() {
                getView().finishAct(DELETE_DRIFT);
                dialog.dismiss();
            }

            @Override
            public void rightClickListener() {
                getView().finishAct(SAVE_DRIFT);
                dialog.dismiss();
            }
        });
        dialog = builder.create();
        dialog.show();
    }

    /**
     * 保存草稿
     *
     * @param cg_id     草稿id
     * @param serial_id 文集id
     * @param number    正文字数
     * @param title     标题
     * @param content   内容
     * @param topImgUrl 头图
     */
    public void saveDraft(int cg_id, int serial_id, int number, String title, String content, String topImgUrl) {
        SavaDraftBody body = new SavaDraftBody();
        body.setTopImg(topImgUrl);
        body.setTitle(title);
        body.setContent(StringUtils.toHTMLString(content));
        Map<String, Object> map = new HashMap<>();
        map.put("user_id", UserInfoUtils.getUserId());
        map.put("cg_id", cg_id);
        map.put("serial_id", serial_id);
        map.put("number", number);
        RetorfitService.saveDraft(UserInfoUtils.getUserId(), serial_id, cg_id, number,
                Common.encryptionSign(map), body)
                .compose(getView().<SaveDraftResponse>bindToLife()).doOnSubscribe(new Action0() {
            @Override
            public void call() {

            }
        }).subscribe(new Subscriber<SaveDraftResponse>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(SaveDraftResponse object) {
                if (object.getErrCode() == 0) {
                    getView().saveDraftSuccess(object);
                } else {
                    ToastUtils.show(object.getErrMsg());
                }
            }
        });
    }

    /**
     * 获取草稿内容
     *
     * @param contribute_id 草稿id
     */
    public void getDraft(int contribute_id) {
        Map<String, Object> map = new HashMap<>();
        map.put("contribute_id", contribute_id);
        RetorfitService.getDraft(contribute_id,
                Common.encryptionSign(map))
                .compose(getView().<DraftResponse>bindToLife()).doOnSubscribe(new Action0() {
            @Override
            public void call() {

            }
        }).subscribe(new Subscriber<DraftResponse>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(DraftResponse object) {
                if (object.getErrCode() == 0) {
                    getView().callBackDraftContent(object);
                } else {
                    ToastUtils.show(object.getErrMsg());
                }
            }
        });
    }

    /**
     * 下一步;投稿设置
     *
     * @param draftId         草稿id
     * @param articleFloderId 文集id
     * @param articleTitle    标题
     * @param articleContent  内容
     * @param topImgUrl       头图
     */
    public void toSettingAct(int draftId, int articleFloderId, String articleTitle
            , String articleContent, String topImgUrl) {
        Intent intent = new Intent(mContext, SubmitArticleSettingActivity.class);
        String htmlStr = StringUtils.toHTMLString(articleContent);
        SavaDraftBody body = new SavaDraftBody();
        body.setTitle(articleTitle);
        body.setContent(htmlStr);
        body.setTopImg(topImgUrl);
        intent.putExtra(Constant.DRAFT_DOBY, body);
        intent.putExtra(Constant.FOLDER_ID, articleFloderId);
        intent.putExtra(Constant.DRAFT_ID, draftId);
        intent.putExtra(Constant.ARTICLE_LENGTH, articleContent.length());
        activity.startActivityForResult(intent, FINISH_SUBMIT_ARTICLE);
    }

    /**
     * 选择文件夹
     */
    public void toArticleFloderAct() {
        Intent intent = new Intent(mContext, SelectFloderActivity.class);
        intent.putExtra(Constant.INTENT_TYPE, SubmitArticleActivity.class.getSimpleName());
        activity.startActivityForResult(intent, SUBMIT_ARTICLE_SELECT_FLODER);
    }

    public boolean checkRule(EditText title, EditText content) {
        if (TextUtils.isEmpty(title.getText().toString())) {
            ToastUtils.show("为文章取一个标题吧");
            return false;
        }
        if (TextUtils.isEmpty(content.getText().toString())) {
            ToastUtils.show("您还没有编辑内容");
            return false;
        }
        return true;
    }

    /**
     * @param requestCode     ActivityForResult
     * @param withAspectRatio 是否限制图片宽高比例
     */
    public void getPicture(final int requestCode, final boolean withAspectRatio) {
        if (!XXPermissions.isHasPermission(mContext, permissions)) {
            XXPermissions.with((Activity) mContext).permission(permissions).request(new OnPermission() {
                @Override
                public void hasPermission(List<String> granted, boolean isAll) {
                    toGallery(requestCode, withAspectRatio);
                }

                @Override
                public void noPermission(List<String> denied, boolean quick) {
                    XXPermissions.gotoPermissionSettings(mContext);
                }
            });
        } else {
            toGallery(requestCode, withAspectRatio);
        }

    }

    /**
     * @param requestCode     ActivityForResult
     * @param withAspectRatio 是否限制图片宽高比例
     */
    private void toGallery(int requestCode, boolean withAspectRatio) {
        PictureSelectionModel gallery = PictureSelector.create((Activity) mContext)
                .openGallery(PictureMimeType.ofImage());
        //上传头图限制4：3尺寸，文章插图可以自行选中图片尺寸
        if (withAspectRatio) {
            gallery.withAspectRatio(4, 3);
        } else {
            gallery.freeStyleCropEnabled(true)
                    .withAspectRatio(4, 3);
        }
        gallery.selectionMode(PictureConfig.SINGLE)
                .previewImage(true)
                .compress(true)
                .isCamera(true)
                .enableCrop(true)
                .forResult(requestCode);
    }

    /**
     * 修复所要上传的图片
     * 1、部分手机相册的图片显示的是正常角度，实际上存在图片角度被旋转的情况
     * 2、图片大小限制在3M以内
     */
    public void repairImg(String path, final int requestCode) {
        activity.showLoading(true);
        long size = 3 * 1024 * 1024;
        File file;
        int degree = BitmapUtils.getBitmapDegree(path);
        //如果图片被旋转了，修复旋转之后再上传
        if (degree != 0) {
            Bitmap bitmap = null;
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(path);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            bitmap = BitmapFactory.decodeStream(fis);
            bitmap = BitmapUtils.rotateBitmapByDegree(bitmap, degree);
            file = new File(FileUtils.initPath() + "articlePicture.jpg");//将要保存图片的路径
            try {
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
                bos.flush();
                bos.close();
                if (FileUtils.getFileSize(file) > size) {
                    compressImage(file, requestCode);
                } else {
                    upload(file, requestCode);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            file = new File(path);
            try {
                if (FileUtils.getFileSize(file) > size) {
                    compressImage(file, requestCode);
                } else {
                    upload(file, requestCode);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 压缩图片
     */
    private void compressImage(File file, final int requestCode) {
        Luban.with(mContext)
                .load(file.getAbsolutePath())
                .ignoreBy(100)//不压缩的阈值，单位为K
                .setTargetDir(FileUtils.initPath())
                .filter(new CompressionPredicate() {
                    @Override
                    public boolean apply(String path) {
                        return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
                    }
                })
                .setCompressListener(new OnCompressListener() {
                    @Override
                    public void onStart() {
                    }

                    @Override
                    public void onSuccess(File file) {
                        upload(file, requestCode);
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        if (activity.isShowLoading()) {
                            activity.showLoading(false);
                        }
                    }
                }).launch();
    }

    /**
     * 上传图片
     *
     * @param file
     * @param requestCode
     */
    private void upload(File file, final int requestCode) {
        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part body = MultipartBody.Part.createFormData("AndroidFile", file.getName(), requestFile);
        FileUploadService.upload(body).doOnSubscribe(new Action0() {
            @Override
            public void call() {

            }
        }).compose(getView().<UpLoadImage>bindToLife()).subscribe(new Subscriber<UpLoadImage>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {
                if (activity.isShowLoading()) {
                    activity.showLoading(false);
                }
            }

            @Override
            public void onNext(UpLoadImage upLoadImageResult) {
                if (activity.isShowLoading()) {
                    activity.showLoading(false);
                }
                if (upLoadImageResult.getErrCode() == 0) {
                    if (requestCode == UPLOAD_ILLUSTRATION) {//文章内容插图
                        getView().uploadInsertImgSuccess(upLoadImageResult);
                    } else if (requestCode == UPLOAD_COVER) {//文章上传封面图片
                        getView().uploadTopImgSuccess(upLoadImageResult);
                    }
                } else {
                    ToastUtils.show(upLoadImageResult.getErrMsg());
                }
            }
        });
    }

    /**
     * 将草稿内容中的图片url转成bitmap
     */
    public void urlsToBitmaps(final List<String> urls) {
        this.urls = urls;
        Glide.with(mContext).asBitmap().load(urls.get(count)).into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                bitmapMap.put(urls.get(count), resource);
                mHandler.post(runnable);
            }
        });
    }

    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            count++;
            if (count < urls.size()) {
                urlsToBitmaps(urls);
            } else {
                getView().callBackDraftBitmaps(bitmapMap);
            }
        }
    };

    /**
     * 处理文章内容，把内容中的图片和文本分离出来
     */
    public void dealWithContent(final String html, final Map<String, Bitmap> bitmaps) {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) {
                List<String> textList = StringUtils.cutStringByImgTag(html);
                for (int i = 0; i < textList.size(); i++) {
                    String text = textList.get(i);
                    emitter.onNext(text);
                }
            }
        })
                .subscribeOn(Schedulers.io())//生产事件在io
                .observeOn(AndroidSchedulers.mainThread())//消费事件在UI线程
                .subscribe(new Observer<String>() {
                    @Override
                    public void onComplete() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        ToastUtils.show("解析错误：图片不存在或已损坏");
                        LogUtil.e("onError: " + e.getMessage());
                    }

                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(String text) {
                        if (text.contains("<img") && text.contains("src=")) {
                            String imgSrcs = StringUtils.getImgSrc(text);
                            LogUtil.d("dealWithContent", imgSrcs);
                            Bitmap bitmap = bitmaps.get(imgSrcs);
                            getView().insertConentImg(imgSrcs, bitmap);
                        } else {
                            String result = Html.fromHtml(text).toString().trim();
                            LogUtil.d("dealWithContent", result);
                            if (!TextUtils.isEmpty(result))
                            getView().insertContentText(result + "\n");
                        }
                    }
                });
    }

    @Override
    public void detachView() {
        super.detachView();
        mHandler.removeCallbacks(runnable);
    }
}
